/*
=======================================================================

  Infiltrator - BOTS
  
=======================================================================
*/
#include "g_local.h"

#include "bots_game2cgame.h"

#include "bg_local.h"
#include "bots_local.h"
#include "bots_infiltrator.h"

#define DISGUISE_TIME	30000

void bots_updateClientData_infiltrator(gentity_t *self, bots_g2cg_infiltrator_t *p) {
	if (!self->client)
		return;

	// Proxies? grenade/weapon modes?
	p->weapons.gren1		= self->client->i_numDecoys;
	p->weapons.gren2		= 0;
	p->weapons.grenademode	= self->client->qb_decoyGrenMode;
	p->weapons.weaponmode 	= 0;

	BOTS_SETBIT(p->bits, self->client->qb_stealMode,	BOTS_G2CG_INFILTRATOR_STEAL);

	p->sDisguiseClass = self->client->i_disguiseClass;
	if (self->client->i_disguiseStopTime == INT_MAX)
		p->sDisguiseTime = -1;
	else {
		int iTime = ceil((self->client->i_disguiseStopTime - level.time)/1000);

		p->sDisguiseTime = iTime>=0?iTime:-2;
	}
}

/////////////////////////////////////////////
//
// BOTS_get_disguise_skin
//
// This function is used when the infiltrator is disguising.  It is called
// from ClientUserInfoChanged in g_client.c.
//
// RETURN:
//	char* model - model string
//
void BOTS_get_disguise_skin(gentity_t* ent, char* model)
{
	int team;
	
	// infiltrator can disguise as his own team - take pressure off the captain
	// I seriously doubt this will be used much.
	if (ent->bots_team == TEAM_RED)
	{
		if (ent->client->qb_enemyDisguise)
			team = TEAM_RED;
		else
			team = TEAM_BLUE;		
	}
	else
	{
		if (ent->client->qb_enemyDisguise)
			team = TEAM_BLUE;
		else
			team = TEAM_RED;
	}	

	// should be the opposite of bots_GetClientSkin - team wise anyway...
	switch(ent->client->i_disguiseClass)
	{
	case BOTS_CAPTAIN:
		if (team == TEAM_RED)
			Q_strncpyz( model, "fcaptain/fcaptain2", MAX_QPATH );
		else
			Q_strncpyz( model, "mcaptain/captain", MAX_QPATH );
		break;
	case BOTS_BODYGUARD:
		if (team == TEAM_RED)
			Q_strncpyz( model, "female/fbodyguard", MAX_QPATH );
		else
			Q_strncpyz( model, "male/bodyguard", MAX_QPATH );
		break;
	case BOTS_SNIPER:
		if (team == TEAM_RED)
			Q_strncpyz( model, "female/fsniper", MAX_QPATH );
		else
			Q_strncpyz( model, "male/sniper", MAX_QPATH );
		break;
	case BOTS_SOLDIER:
		if (team == TEAM_RED)
			Q_strncpyz( model, "female/fsoldier", MAX_QPATH );
		else
			Q_strncpyz( model, "male/soldier", MAX_QPATH );
		break;
	case BOTS_BERZERKER:
		if (team == TEAM_RED)
			Q_strncpyz( model, "female/fberzerker", MAX_QPATH );
		else
			Q_strncpyz( model, "male/berzerker", MAX_QPATH );
		break;
	case BOTS_INFILTRATOR:
		if (team == TEAM_RED)
			Q_strncpyz( model, "female/finfiltrator", MAX_QPATH );
		else
			Q_strncpyz( model, "male/infiltrator", MAX_QPATH );
		break;
	case BOTS_KAMIKAZEE:
		if (team == TEAM_RED)
			Q_strncpyz( model, "female/fkamikazee", MAX_QPATH );
		else
			Q_strncpyz( model, "male/kamikazee", MAX_QPATH );
		break;
	case BOTS_NURSE:
		if (team == TEAM_RED)
			Q_strncpyz( model, "female/fnurse", MAX_QPATH );
		else
			Q_strncpyz( model, "male/nurse", MAX_QPATH );
		break;
	case BOTS_SCIENTIST:
		if (team == TEAM_RED)
			Q_strncpyz( model, "fscientist/fscientist", MAX_QPATH );
		else
			Q_strncpyz( model, "mscientist/scientist", MAX_QPATH );
		break;
	}
}

/////////////////////////////////////////////
//
// BOTS_disguise
//
// This function is basically called from the disguise menu.  It figures
// out which class we are disguising as and then calls to ClientUserinfoChanged
// to make the changes
//
void BOTS_disguise(int clientNum)
{
	gentity_t* ent = g_entities + clientNum;
	char	fromUI[MAX_TOKEN_CHARS];

	if (!ent->client)
		return;

	if (trap_Argc() > 1)
		trap_Argv( 1, fromUI, sizeof( fromUI ) );
	else
		G_Printf( S_COLOR_RED "ERROR: invalid disguise command\n" );

	ent->client->i_disguiseClass = atoi(fromUI);
	ent->client->qb_disguiseMode = qtrue;

	if (ent->client->qb_enemyDisguise)
		ent->client->i_disguiseStopTime = level.time + DISGUISE_TIME;
	else
		ent->client->i_disguiseStopTime = INT_MAX;

	ClientUserinfoChanged( clientNum );

	//csfix: trap_SendServerCommand( -1, "loaddefered\n" );
}

/////////////////////////////////////////////
//
// BOTS_disguise_setup
//
// This function will check to see if the client can use the disguise command.
// If he can, we will pass control to the UI module.
//
void BOTS_disguise_setup(int clientNum, qboolean enemy_disguise)
{
	gentity_t* ent = g_entities + clientNum;

	if (!ent->client)
		return;

	// check to see if this class can disguise
	if (ent->bots_class != BOTS_INFILTRATOR)
	{
		BOTS_cp_console(clientNum, "Only the Infiltrator can disguise.");
		return;
	}

	// check to see if we have the flag
	if (ent->client->ps.powerups[PW_BLUEFLAG]	||
		ent->client->ps.powerups[PW_REDFLAG]	||
		ent->client->keyindex)
	{
		BOTS_cp_console(clientNum, "You can not disguise with the flag.");
		return;
	}

	// check to see if we are level 2 or greater
	if (ent->client->pers.classlevel < 2 && enemy_disguise)
	{
		BOTS_cp_console(clientNum, "You must be at least level 2 to disguise as the enemy.");
		ent->client->qb_disguiseMode = qfalse;
		return;
	}

	// check ammo
	if (ent->client->ps.ammo[WP_BFG] < 25)
	{
		BOTS_cp_console( clientNum, "You need at least 25 cells to disguise.");
		return;
	}
	ent->client->ps.ammo[WP_BFG] -= 25;
	ent->client->qb_enemyDisguise = enemy_disguise;


	trap_SendServerCommand(clientNum, "disguise_data_complete");
}

/////////////////////////////////////////////
//
// BOTS_steal
//
// This function will toggle the infiltrator's steal mode.
//
void BOTS_steal(int clientNum)
{
	gentity_t* ent = g_entities + clientNum;

	if (!ent->client)
		return;

	// check to see if this class can steal
	if (ent->bots_class != BOTS_INFILTRATOR)
	{
		BOTS_cp_console(clientNum, "Only the Infiltrator can steal.");
		return;
	}

	ent->client->qb_stealMode = !ent->client->qb_stealMode;

	/*
	if (ent->client->qb_stealMode)
		BOTS_cp_console(clientNum, "Stealing enabled.");
	else
		BOTS_cp_console(clientNum, "Stealing disabled.");
	*/
}

/////////////////////////////////////////////
//
// BOTS_InfiltratorCommands
//
// This will parse the passed cmd string and call to the correct functions.
// 
// RETURNS
//    qfalse : cmd is not an infiltrator command
//	  qtrue	 : cmd is an infiltrator command
//
qboolean BOTS_InfiltratorCommands(int clientNum, char* cmd)
{
	if (Q_stricmp (cmd, "steal") == 0 )
	{
		BOTS_steal(clientNum);
		return qtrue;
	}
	else if (Q_strncmp (cmd, "enemy_disguise", strlen ("enemy_disguise")) == 0)
	{
		BOTS_disguise_setup(clientNum, qtrue);
		return qtrue;
	}
	else if (Q_strncmp (cmd, "team_disguise", strlen ("team_disguise")) == 0)
	{
		BOTS_disguise_setup(clientNum, qfalse);
		return qtrue;
	}

	return qfalse;
}

/////////////////////////////////////////////
//
// BOTS_ClientThink_infiltrator
//
// Infiltrator think routine.  Called once for each client think if
// the client is an infiltrator.
//
void BOTS_ClientThink_infiltrator(gentity_t* ent)
{
	if (ent->health <= 0)
		return;

	if (ent->client->qb_disguiseMode)
	{
		if (ent->client->i_disguiseStopTime < level.time)
		{
			ent->client->qb_disguiseMode = qfalse;
			ClientUserinfoChanged( ent->s.clientNum );

			// force the loading of the players model to all clients
			//csfix: trap_SendServerCommand( -1, "loaddefered\n" );
		}		
	}
}
